
package usuario.model;

import bibliinfo.FrameMain;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import utilitarios.Conexao;
import utilitarios.Dao;

public class UsuarioDao extends Dao<Usuario, Endereco, Contato, Data> {

    @Override
    public void create(Usuario usuario, Endereco endereco, Contato contato, Data data) {
        
        java.sql.Connection con = Conexao.getConnection();
        
        try{
            //criando ponto para mudanças de modo experimental            
            con.setAutoCommit(false);            
            //gravando dados da tabela usuario
            String sql = "insert into usuario(rg, nome, sexo, ativo, suspenso, observacoes ) "
                    +"values (?,?,?,?,?,?)";
            
            try(PreparedStatement stm = con.prepareStatement(sql)){
                stm.setLong(1, usuario.getRg());
                stm.setString(2, usuario.getNome());
                stm.setString(3, usuario.getSexo());
                stm.setBoolean(4, usuario.getAtivo());
                stm.setBoolean(5, usuario.getSuspenso());
                stm.setString(6, usuario.getObservacoes());
                //gravando informações
                stm.executeUpdate();
            }
            
            sql = "insert into endereco (rg, estado, cidade, cep, bairro, rua, num_casa) "
                    +"values (?,?,?,?,?,?,?)";  
            
            try(PreparedStatement stm = con.prepareStatement(sql)){
                
                stm.setLong(1, endereco.getRg());
                stm.setString(2, endereco.getEstado());
                stm.setString(3, endereco.getCidade());
                stm.setString(4, endereco.getCep());
                stm.setString(5, endereco.getBairro());
                stm.setString(6, endereco.getRua());
                stm.setString(7, endereco.getNumCasa());                
                //granvando informações
                stm.executeUpdate();
                
            }
           
            sql = "insert into contato (rg, tel_1, tel_2, tel_3, tel_4, email_1, email_2) "
                    +"values (?,?,?,?,?,?,?);";
           
            try(PreparedStatement stm = con.prepareStatement(sql)){
                
                stm.setLong(1, contato.getRg());
                stm.setString(2, contato.getTel_1());
                stm.setString(3, contato.getTel_2());
                stm.setString(4, contato.getTel_3());
                stm.setString(5, contato.getTel_4());
                stm.setString(6, contato.getEmail_1());
                stm.setString(7, contato.getEmail_2());                
                //gravando informações
                stm.executeUpdate();
                
            }
        
            sql = "insert into data (rg, data_nasc, data_cad, data_inicio_multa, data_fim_multa) "
                    +"values (?,?,?,?,?)";
            
            try(PreparedStatement stm = con.prepareStatement(sql)){
                
                stm.setLong(1, data.getRg());                              
                stm.setDate(2, data.getDataNascSQL());
                stm.setDate(3, data.getDataCadSQL());               
                stm.setDate(4, data.getDataInicioMultaSQL());
                stm.setDate(5, data.getDataFimMultaSQL());                
               
                //gravando informações                
                stm.executeUpdate();                
            }
            
            con.commit();
        }catch(Exception e){
            try {
                con.rollback();
                String erro = "Houve um erro ao gravar os dados do usuário no banco de dados";
                JOptionPane.showMessageDialog(FrameMain.userFrameDados, erro, "Erro", 0);
                e.printStackTrace();
            } catch (SQLException ex) {
                Logger.getLogger(UsuarioDao.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    @Override
    public List readA() {
        List<Usuario> listaUser = new ArrayList<Usuario>();
        String sql = "select * from usuario";
        Connection con = Conexao.getConnection();
        try(PreparedStatement stm = con.prepareStatement(sql);
                ResultSet resultado = stm.executeQuery()){
            
            while(resultado.next() == true){
                Usuario usuario = new Usuario();
                
                usuario.setRg(resultado.getLong(1));
                usuario.setNome(resultado.getString(2));
                usuario.setSexo(resultado.getString(3));
                usuario.setAtivo(resultado.getBoolean(4));
                usuario.setSuspenso(resultado.getBoolean(5));
                usuario.setObservacoes(resultado.getString(6));
                
                listaUser.add(usuario);
            }           
        }catch(SQLException e){
            String erro = "Houve um erro ao ler as informações do banco de dados";               
            JOptionPane.showMessageDialog(FrameMain.userFrameDados, erro, "Erro", 0);
            e.printStackTrace();
        }
        
        return listaUser;
    }

    @Override
    public List readB() {
        List<Endereco> listaEnd = new ArrayList<Endereco>();
        String sql = "select * from endereco";
        Connection con = new Conexao().getConnection();
        try(PreparedStatement stm = con.prepareStatement(sql);
                ResultSet resultado = stm.executeQuery()){
            while (resultado.next() == true) {
                Endereco endereco = new Endereco();
                
                endereco.setRg(resultado.getLong(1));
                endereco.setEstado(resultado.getString(2));
                endereco.setCidade(resultado.getString(3));
                endereco.setCep(resultado.getString(4));
                endereco.setBairro(resultado.getString(5));
                endereco.setRua(resultado.getString(6));
                endereco.setNumCasa(resultado.getString(7));
                
                listaEnd.add(endereco);
            }
            
        }catch(SQLException e){
            String erro = "Houve um erro ao ler as informações do banco de dados";
            JOptionPane.showMessageDialog(FrameMain.userFrameDados, erro, "Erro", 0);
        }
        return listaEnd;
    }    
    @Override
    public List readC() {
        List<Contato> listacontato = new ArrayList<Contato>();
        String sql = "select * from contato";
        Connection con = Conexao.getConnection();
        try(PreparedStatement stm = con.prepareStatement(sql);
                ResultSet resultado = stm.executeQuery()){
        
            while(resultado.next() == true){                
                Contato contato = new Contato();
                
                contato.setRg(resultado.getLong(1));
                contato.setTel_1(resultado.getString(2));
                contato.setTel_2(resultado.getString(3));
                contato.setTel_3(resultado.getString(4));
                contato.setTel_4(resultado.getString(5));
                contato.setEmail_1(resultado.getString(6));
                contato.setEmail_2(resultado.getString(7));
                
                listacontato.add(contato);
            }
        }catch(SQLException e){
            String erro = "Houve um erro ao ler as informações do banco de dados";
            JOptionPane.showMessageDialog(FrameMain.userFrameDados, erro, "Erro", 0);
            e.printStackTrace();
        }
        return listacontato;
    }
    @Override
    public List readD() {
        List<Data> listaData = new ArrayList<Data>();
        String sql = "select * from data";
        Connection con = Conexao.getConnection();
        try(PreparedStatement stm = con.prepareStatement(sql);
                ResultSet resultado = stm.executeQuery()){
            
            while(resultado.next() == true){
                Data data = new Data();
                Date dataUtil = new Date();
                data.setRg(resultado.getLong(1));
                
                dataUtil = resultado.getDate(2);
                data.calendar.setTime(dataUtil);
                data.instanciarDataNasc();
                data.InstanciarDataNascSQL();
                
                dataUtil = resultado.getDate(3);
                data.calendar.setTime(dataUtil);
                data.instanciarDataCad();
                data.instanciarDataCadSQL();
                
                dataUtil = resultado.getDate(4);
                data.calendar.setTime(dataUtil);
                data.instanciarDataInicioMulta();
                data.instanciarDataInicioMultaSQL();
                
                dataUtil = resultado.getDate(5);
                data.calendar.setTime(dataUtil);
                data.instanciarDataFimMulta();
                data.instanciarDataFimMultaSQL();
                
                listaData.add(data);
            }
        
        }catch(SQLException e){            
            String erro = "Houve um erro ao ler as informações do banco de dados";
            JOptionPane.showMessageDialog(FrameMain.userFrameDados, erro, "Erro", 0);
            e.printStackTrace();
        }        
        return listaData;
    }       
   
    public List read(String pesquisa, int i){    
        List<Usuario> listaUser = new ArrayList<Usuario>();
        String sql = "";
        if(i == 1){
            sql = "select * from usuario where nome like ?";            
        }else if (i == 2){
            sql = "select * from usuario where rg like ?";
        }        
        Connection con = Conexao.getConnection();           
        try(PreparedStatement stm = con.prepareStatement(sql)){            
            stm.setString(1, pesquisa);            
            ResultSet resultado = stm.executeQuery(); 
            while(resultado.next() == true){
                Usuario usuario = new Usuario();
                
                usuario.setRg(resultado.getLong(1));
                usuario.setNome(resultado.getString(2));
                usuario.setSexo(resultado.getString(3));
                usuario.setAtivo(resultado.getBoolean(4));
                usuario.setSuspenso(resultado.getBoolean(5));
                usuario.setObservacoes(resultado.getString(6));
                
                listaUser.add(usuario);
            }
            
        }catch(SQLException e){
                String erro = "Houve um erro ao ler as informações do banco de dados";
                JOptionPane.showMessageDialog(FrameMain.userFrameMain, erro, "Erro", 0);
                e.printStackTrace();
        }
        return listaUser;
    }

    @Override
    public void update(Usuario usuario, Endereco endereco, Contato contato, Data data){        
        
        Connection con = Conexao.getConnection();        
        String sql = "update usuario set "
                +"rg=?, nome=?, sexo=?, ativo=?, suspenso=?, observacoes=? where rg=?";
        try{
            //criando ponto para mudanças experimentais
            con.setAutoCommit(false);
            try(PreparedStatement stm = con.prepareStatement(sql)){
                stm.setLong(1, usuario.getRgNovo());
                stm.setString(2, usuario.getNome());
                stm.setString(3, usuario.getSexo());
                stm.setBoolean(4, usuario.getAtivo());
                stm.setBoolean(5, usuario.getSuspenso());
                stm.setString(6, usuario.getObservacoes());
                stm.setLong(7, usuario.getRg());
                
                stm.executeUpdate();
            }
            
            sql = "update endereco set "
                    +"estado=?, cidade=?, cep=?, bairro=?, rua=?, num_casa=? where rg=?";
            try(PreparedStatement stm = con.prepareStatement(sql)){
                stm.setString(1, endereco.getEstado());
                stm.setString(2, endereco.getCidade());
                stm.setString(3, endereco.getCep());
                stm.setString(4, endereco.getBairro());
                stm.setString(5, endereco.getRua());
                stm.setString(6, endereco.getNumCasa());
                stm.setLong(7, endereco.getRg());
                
                stm.executeUpdate();
            }
            
            sql = "update contato set "
                    +"tel_1=?, tel_2=?, tel_3=?, tel_4=?, email_1=?, email_2=? where rg=?";
            try(PreparedStatement stm = con.prepareStatement(sql)){
                stm.setString(1, contato.getTel_1());
                stm.setString(2, contato.getTel_2());
                stm.setString(3, contato.getTel_3());
                stm.setString(4, contato.getTel_4());
                stm.setString(5, contato.getEmail_1());
                stm.setString(6, contato.getEmail_2());
                stm.setLong(7, contato.getRg());
                
                stm.executeUpdate();
            }
            
            sql = "update data set "
                    +"data_nasc=?, data_cad=?, data_inicio_multa=?, data_fim_multa=? where rg=?";
            try(PreparedStatement stm = con.prepareStatement(sql)){
                stm.setDate(1, data.getDataNascSQL());
                stm.setDate(2, data.getDataCadSQL());
                stm.setDate(3, data.getDataInicioMultaSQL());
                stm.setDate(4, data.getDataFimMultaSQL());
                stm.setLong(5, data.getRg());
                
                stm.executeUpdate();
            }
            
            /*Permitindo com que as mudanças experimentais sejam executas permanentimente*/
            con.commit();
        }catch(Exception e){
            try {
                con.rollback();
                String erro = "Houve um erro ao gravar os dados do usuário no banco de dados";
                JOptionPane.showMessageDialog(FrameMain.userFrameDados, erro, "Erro", 0);
                e.printStackTrace();
            } catch (SQLException ex) {
                Logger.getLogger(UsuarioDao.class.getName()).log(Level.SEVERE, null, ex);
            };
        }
    }    

    @Override
    public void delete(Usuario usuario) {
        Connection con = Conexao.getConnection();
        String sql = "update usuario set "
                +"ativo=? where rg=?";
        try(PreparedStatement stm = con.prepareStatement(sql)){
            //criando ponto para alterações de modo experimental no banco
            con.setAutoCommit(false);
            stm.setBoolean(1, usuario.getAtivo());
            stm.setLong(2, usuario.getRg());
            
            //execultando operação
            stm.executeUpdate();            
            //efetuando operação de modo permanente
            con.commit();
        }catch(Exception e){
            try {
                con.rollback();
                String erro = "Houve um erro efetuar a operação no banco de dados";
                JOptionPane.showMessageDialog(FrameMain.userFrameDados, erro, "Erro", 0);
                e.printStackTrace();
            } catch (SQLException ex) {
                Logger.getLogger(UsuarioDao.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }    
}
